﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading;

namespace LicenseLib
{
    /// <summary>
    /// 获取电脑的BIOS\CPU等信息
    /// </summary>
    public class MachineConfigManager
    {
        private static MachineConfigManager machineCode;

        /// <summary>
        /// 按照勾选的对象，配置需要获取的硬件信息
        /// </summary>
        /// <param name="pcCheckKey"></param>
        /// <returns></returns>
        public static string GetMachineCodeString(string pcCheckKey)
        {
            if (machineCode == null)
                machineCode = new MachineConfigManager();
            var enKeyString = new StringBuilder();
            enKeyString.Append($"{machineCode.GetBios()};");
            var enKeys = pcCheckKey.ToArray();
            if (enKeys.Length > 0 && enKeys[0].ToString() == "1")
                enKeyString.Append($"{machineCode.GetCpuInfo()};");
            else
                enKeyString.Append(";");
            if (enKeys.Length > 1 && enKeys[1].ToString() == "1")
                enKeyString.Append($"{machineCode.GetHDid()};");
            else
                enKeyString.Append(";");
            if (enKeys.Length > 2 && enKeys[2].ToString() == "1")
            {
                var mac = machineCode.GetMoAddress();
                if (!string.IsNullOrEmpty(mac))
                {
                    enKeyString.Append($"{mac};");
                }
                else
                    enKeyString.Append(";");
            }
            else
                enKeyString.Append(";");
            return enKeyString.ToString();
        }

        /// <summary>
        /// 获取bios序列号
        /// </summary>
        /// <returns></returns>
        private string GetBios()
        {
            Stopwatch sw = Stopwatch.StartNew();
            string biosInfo = "";
            try
            {
                using (ManagementClass cimobject = new ManagementClass("Win32_BaseBoard"))
                {
                    ManagementObjectCollection moc = cimobject.GetInstances();

                    foreach (ManagementObject mo in moc)
                    {
                        biosInfo = mo.Properties["SerialNumber"].Value.ToString();
                        break;
                    }
                }
                if (biosInfo == "serial1")
                {
                    biosInfo = "";
                }
            }
            catch (Exception)
            {
                biosInfo = "";
            }
            sw.Stop();
            Console.WriteLine($"Bios:{sw.ElapsedMilliseconds}");
            return biosInfo.ToString();
        }

        ///   <summary> 
        ///   获取cpu序列号     
        ///   </summary> 
        ///   <returns> string </returns> 
        private string GetCpuInfo()
        {
            Stopwatch sw = Stopwatch.StartNew();
            string cpuInfo = "";
            try
            {
                using (ManagementClass cimobject = new ManagementClass("Win32_Processor"))
                {
                    ManagementObjectCollection moc = cimobject.GetInstances();

                    foreach (ManagementObject mo in moc)
                    {
                        cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
                        break;
                    }
                }
            }
            catch (Exception)
            {
                cpuInfo = "";
            }
            sw.Stop();
            Console.WriteLine($"CPU:{sw.ElapsedMilliseconds}");
            return cpuInfo.ToString();
        }

        ///   <summary> 
        ///   获取硬盘ID     
        ///   </summary> 
        ///   <returns> string </returns> 
        private string GetHDid()
        {
            Stopwatch sw = Stopwatch.StartNew();
            try
            {
                List<string> hdList = new List<string>();
                using (ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive"))
                {
                    ManagementObjectCollection moc1 = cimobject1.GetInstances();
                    foreach (ManagementObject mo in moc1)
                    {
                        hdList.Add((string)mo.Properties["SerialNumber"].Value);
                    }
                }
                sw.Stop();
                Console.WriteLine($"Disk:{sw.ElapsedMilliseconds}");
                return string.Join(",", hdList);
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }

        ///   <summary> 
        ///   获取网卡硬件地址 
        ///   </summary> 
        ///   <returns> string </returns> 
        private string GetMoAddress()
        {
            Stopwatch sw = Stopwatch.StartNew();
            try
            {

                //=========此方案必须启动WMI服务==========
                //using (ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"))
                //{
                //    ManagementObjectCollection moc2 = mc.GetInstances();
                //    foreach (ManagementObject mo in moc2)
                //    {
                //        if ((bool)mo["IPEnabled"] == true)
                //        {
                //            MoAddress += mo["MacAddress"].ToString() + "@";
                //        }
                //    }
                //}

                var macs = GetMACByCmd();
                if (macs == null) return string.Empty;
                sw.Stop();
                Console.WriteLine($"Mac:{sw.ElapsedMilliseconds}");
                return string.Join(",", macs);
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }


        //1. 取得设备硬盘的物理序列号    仅支持windows桌面程序(unity用不了)
        public static List<string> GetSerialNumber()
        {
            List<string> serial_number_list = new List<string>();
            try
            {
                //Win32_PhysicalMedia或者 Win32_DiskDrive
                ManagementObjectSearcher searcher =
                new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");

                foreach (ManagementObject info in searcher.Get())
                {
                    var def = info.Properties["SerialNumber"].ToString().Trim();
                    string serial_number = info["SerialNumber"].ToString().Trim();
                    serial_number_list.Add(serial_number);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return serial_number_list;
        }

        //2. 取得设备硬盘的物理序列号   unity可用
        public static string GetSerialNumberByCmd()
        {
            string strInput = "wmic diskdrive get SerialNumber";
            Process p = new Process();
            //设置要启动的应用程序
            p.StartInfo.FileName = "cmd.exe";
            //是否使用操作系统shell启动
            p.StartInfo.UseShellExecute = false;
            // 接受来自调用程序的输入信息
            p.StartInfo.RedirectStandardInput = true;
            //输出信息
            p.StartInfo.RedirectStandardOutput = true;
            // 输出错误
            p.StartInfo.RedirectStandardError = true;
            //不显示程序窗口
            p.StartInfo.CreateNoWindow = true;
            //启动程序
            p.Start();

            Thread.Sleep(1000);
            //向cmd窗口发送输入信息
            p.StandardInput.WriteLine(strInput + "&exit");

            p.StandardInput.AutoFlush = true;

            //获取输出信息
            string strOuput = p.StandardOutput.ReadToEnd();
            //等待程序执行完退出进程
            p.WaitForExit();
            p.Close();

            List<string> serialNumbers = new List<string>();
            string[] temps = strOuput.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < temps.Length; i++)
            {
                serialNumbers.Add(temps[i].Trim());
            }

            if (serialNumbers.Count > 4)
            {
                return serialNumbers[4];
            }
            else
            {
                return "";
            }
        }

        public static List<string> GetMACByCmd()
        {
            try
            {
                string strInput = "ipconfig /all";
                Process p = new Process();
                //设置要启动的应用程序
                p.StartInfo.FileName = "cmd.exe";
                //是否使用操作系统shell启动
                p.StartInfo.UseShellExecute = false;
                // 接受来自调用程序的输入信息
                p.StartInfo.RedirectStandardInput = true;
                //输出信息
                p.StartInfo.RedirectStandardOutput = true;
                // 输出错误
                p.StartInfo.RedirectStandardError = true;
                //不显示程序窗口
                p.StartInfo.CreateNoWindow = true;
                //启动程序
                p.Start();

                Thread.Sleep(1000);
                p.StandardInput.WriteLine(strInput + "&exit");

                p.StandardInput.AutoFlush = true;
                string strOuput = p.StandardOutput.ReadToEnd();
                p.WaitForExit();
                p.Close();

                List<string> serialNumbers = new List<string>();
                string[] temps = strOuput.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                for (int i = 0; i < temps.Length; i++)
                {
                    if (temps[i].Trim().Contains("物理地址")|| temps[i].Trim().Contains("Physical Address"))
                    {
                        if (temps[i].Trim().Contains(":"))
                        {
                            serialNumbers.Add(temps[i].Trim().Split(':')[1].Trim());
                        }
                        else
                        {
                            serialNumbers.Add(temps[i].Trim());
                        }
                    }
                }

                return serialNumbers;

            }
            catch
            {
                return null;
            }
        }
    }
}